
package com.hlkj.pay.app.merchant.ext.impl.fuyou.handler;
/*
 * Hlpay-Plus aggregate payment system.
 * Copyright (c) 2024-2025 Hlpay Team Copyright has the right of final interpretation.
 */

import java.net.URLEncoder;
import java.util.HashMap;
import java.util.Map;

import javax.annotation.Resource;

import org.springframework.stereotype.Component;
import org.springframework.util.StringUtils;

import com.hlkj.framework.common.pojo.CommonResult;
import com.hlkj.framework.common.util.id.IdUtils;
import com.hlkj.framework.common.util.json.JsonUtils;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessContext;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantAccessQueryContext;
import com.hlkj.pay.app.merchant.ext.dto.access.ChannelMerchantBusinessContext;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.constant.FuYouConstant;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.ElecContract;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.ElecContractSign;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouConfig;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.dto.FuYouJsonResponse;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.HttpUtils;
import com.hlkj.pay.app.merchant.ext.impl.fuyou.utils.SignUtils;
import com.hlkj.pay.enums.MerchantEnum;
import com.hlkj.pay.infrastructure.model.merchant.MerchantAccessInfoDO;
import com.hlkj.pay.infrastructure.model.pay.PayChannelRequestDO;

import lombok.extern.slf4j.Slf4j;

/**
 * @author HlpayTeam
 * @date 2024/10/16 9:10
 */
@Slf4j
@Component
public class FuYouMerchantAccessInfoHandler extends FuYouMerchantCommonParamsHandle {

    @Resource
    private FuYouFtpHandler fuYouFtpHandler;

    /**
     *
     * @param channelMerchantAccessContext
     */
    public void merchantAccess(ChannelMerchantAccessContext channelMerchantAccessContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = channelConfig(channelMerchantAccessContext.getProviderChannelConfig());
        // 配置转换
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantAccessContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        FuYouConfig fuYouConfig = fuYouConfigCommonResult.getData();
        // 1. 数据初始化
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        channelMerchantAccessContext.setPayChannelRequestDO(payChannelRequestDO);
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            // 参数组装
            // 新增参数转换
            String requestId = IdUtils.getSnowflake().nextIdStr();
            CommonResult<Map<String, Object>> paramsCommonResult = FuYouMerchantParamsHandle.merchantApplyParams(channelMerchantAccessContext, fuYouConfig);
            if (!paramsCommonResult.isSuccess()) {
                channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
                channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
                channelMerchantAccessContext.setRemark(paramsCommonResult.getMsg());
                log.error("富友个人开户 参数校验失败 message: {}", paramsCommonResult.getMsg());
                return;
            }
            String requestUrl = FuYouConstant.MERCHANT_ADD;
            Map<String, Object> params = paramsCommonResult.getData();
            if (StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
                requestUrl = FuYouConstant.MERCHANT_UPDATE;
                params.put("fy_mchnt_cd", merchantAccessInfo.getSubMchId());
                params.remove("license_type");
                params.remove("has_reserve_acnt");
                params.remove("wx_busi_flag");
                params.remove("has_reserve_acnt");
                params.remove("reserve_acnt_no");
                params.remove("reserve_acnt_nm");
                params.remove("reserve_inter_bank_no");
                params.remove("reserve_iss_bank_nm");
                params.remove("reserve_bank_type");
                params.remove("reserve_bank_type");
                params.remove("sales_man");
                params.remove("fast_dzero_num");
            }
            params.put("trace_no", requestId);
            params.put("ins_cd", fuYouConfig.getInsCd());
            params.put("sub_ins_cd", fuYouConfig.getSubInsCd());
            params.put("sign", SignUtils.getMerchantSign(params, fuYouConfig));
            // 记录请求参数
            payChannelRequestDO.setRequestId(requestId);
            payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
            payChannelRequestDO.setRequestUrl(requestUrl);
            String url = domain(channelMerchantAccessContext.isTest()) + requestUrl;
            payChannelRequestDO.setRequestTime(System.currentTimeMillis());
            String mapToXml;
            Map<String, String> requestParams = new HashMap<>();
            if (!StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
                log.info("富友新增进件请求参数:{}", JsonUtils.toJsonString(params));
                mapToXml = SignUtils.convertMapToXml(params);
                log.info("富友新增进件请求xml参数:{}", mapToXml);
                mapToXml = URLEncoder.encode(mapToXml, FuYouConstant.charset);
                requestParams.put("req", mapToXml);
                log.info("富友新增进件req参数:{}", JsonUtils.toJsonString(requestParams));
            }
            else {
                log.info("富友更新进件请求参数:{}", JsonUtils.toJsonString(params));
                mapToXml = SignUtils.convertMapToXml(params);
                log.info("富友更新进件请求xml参数:{}", mapToXml);
                mapToXml = URLEncoder.encode(mapToXml, FuYouConstant.charset);
                requestParams.put("req", mapToXml);
                log.info("富友更新进件req参数:{}", JsonUtils.toJsonString(requestParams));
            }
            String response = HttpUtils.post(url, requestParams);
            // 响应报文验签
            Map<String, Object> resMap = SignUtils.xmlToObject(response);
            if (!StringUtils.hasText(merchantAccessInfo.getSubMchId())) {
                log.info("富友新增进件返回参数:{}", JsonUtils.toJsonString(resMap));
            }else {
                log.info("富友更新进件返回参数:{}", JsonUtils.toJsonString(resMap));
            }
            // 发起请求
            payChannelRequestDO.setResponse(JsonUtils.toJsonString(resMap));
            FuYouMerchantParamsHandle.merchantApplyParamsParse(resMap, channelMerchantAccessContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("富友个人开户请求失败,失败信息 message: {}", e.getMessage());
            channelMerchantAccessContext.setRemark("富友个人开户请求失败,失败信息" + e.getMessage());
            channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantAccessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 生成电子协议以及自动签署电子协议 图片上传
     * 
     * @param channelMerchantBusinessContext
     */
    public void processElecContract(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = channelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
        // 配置转换
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantBusinessContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        FuYouConfig fuYouConfig = fuYouConfigCommonResult.getData();
        // 1. 数据初始化
        PayChannelRequestDO payChannelRequestDO = new PayChannelRequestDO();
        channelMerchantBusinessContext.setPayChannelRequestDO(payChannelRequestDO);
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            // 新增参数转换
            String requestId = IdUtils.getSnowflake().nextIdStr();
            Map<String, Object> params = new HashMap<>();
            params.put("trace_no", requestId);
            params.put("ins_cd", fuYouConfig.getInsCd());
            params.put("mchnt_cd", merchantAccessInfo.getSubMchId());
            params.put("sign", SignUtils.getMerchantSign(params, fuYouConfig));
            String requestUrl = FuYouConstant.MERCHANT_ELEC_GENERATE;
            String url = domain(channelMerchantBusinessContext.isTest()) + requestUrl;
            log.info("富友获取签署协议请求参数:{}", params);
            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("req", JsonUtils.toJsonString(params));
            log.info("富友获取签署协议req参数:{}", JsonUtils.toJsonString(params));
            String response = HttpUtils.post(url, requestParams);
            // 响应报文验签
            log.info("富友获取签署协议返回参数:{}", response);
            ElecContract elecContract = JsonUtils.parseObject(response, ElecContract.class);
            // 协议已审核通过
            if (!StringUtils.hasText(elecContract.getVerify_no())) {
                // 已经审核通过
                payChannelRequestDO.setResponse(response);
                // 上传图片至ftp
                channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SIGN);
            }
            else {
                // 自动签署
                requestId = IdUtils.getSnowflake().nextIdStr();
                params = new HashMap<>();
                params.put("trace_no", requestId);
                params.put("ins_cd", fuYouConfig.getInsCd());
                params.put("mchnt_cd", merchantAccessInfo.getSubMchId());
                params.put("verify_no", elecContract.getVerify_no());
                params.put("contract_no", elecContract.getContract_no());
                params.put("sign", SignUtils.getMerchantSign(params, fuYouConfig));
                requestUrl = FuYouConstant.MERCHANT_ELEC_SIGN;
                // 记录请求参数
                payChannelRequestDO.setRequestId(requestId);
                payChannelRequestDO.setRequestParams(JsonUtils.toJsonString(params));
                payChannelRequestDO.setRequestUrl(requestUrl);
                url = domain(channelMerchantBusinessContext.isTest()) + requestUrl;
                payChannelRequestDO.setRequestTime(System.currentTimeMillis());
                log.info("富友签署协议请求参数:{}", params);
                requestParams = new HashMap<>();
                requestParams.put("req", JsonUtils.toJsonString(params));
                log.info("富友获取签署协议req参数:{}", JsonUtils.toJsonString(params));
                response = HttpUtils.post(url, requestParams);
                // 响应报文验签
                log.info("富友签署协议返回参数:{}", response);
                payChannelRequestDO.setResponse(response);
                ElecContractSign elecContractSign = JsonUtils.parseObject(response, ElecContractSign.class);
                if (FuYouConstant.REQUEST_SUCCESS.equals(elecContractSign.getRet_code())) {
                    // 上传图片至ftp
                    channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SIGN);
                }
                else {
                    channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
                }
            }
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("富友个人开户请求失败,失败信息 message: {}", e.getMessage());
            channelMerchantBusinessContext.setRemark("富友个人开户请求失败,失败信息" + e.getMessage());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }

    }

    /**
     * 进件查询
     *
     * @param channelMerchantBusinessContext
     */
    public void fileProcess(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = channelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
        // 配置转换
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantBusinessContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        FuYouConfig fuYouConfig = fuYouConfigCommonResult.getData();
        CommonResult<String> stringCommonResult = fuYouFtpHandler.zipFile(fuYouConfig, channelMerchantBusinessContext.getMerchantAccessDto());
        if (!stringCommonResult.isSuccess()) {
            channelMerchantBusinessContext.setRemark(stringCommonResult.getMsg());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }
        else {
            channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.AUDIT);
        }
    }

    /**
     *
     * @param channelMerchantBusinessContext
     */
    public void auditProcess(ChannelMerchantBusinessContext channelMerchantBusinessContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = channelConfig(channelMerchantBusinessContext.getProviderChannelConfig());
        // 配置转换
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantBusinessContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        FuYouConfig fuYouConfig = fuYouConfigCommonResult.getData();
        // 1. 数据初始化
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantBusinessContext.getMerchantAccessDto().getMerchantAccessInfo();
        try {
            // 新增参数转换
            String requestId = IdUtils.getSnowflake().nextIdStr();
            Map<String, Object> params = new HashMap<>();
            params.put("trace_no", requestId);
            params.put("ins_cd", fuYouConfig.getInsCd());
            params.put("mchnt_cd", merchantAccessInfo.getSubMchId());
            params.put("sign", SignUtils.getMerchantSign(params, fuYouConfig));
            String requestUrl = FuYouConstant.MERCHANT_ATTACH_CONFIRM;
            // 记录请求参数
            String url = domain(channelMerchantBusinessContext.isTest()) + requestUrl;
            log.info("富友审核请求参数:{}", params);
            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("req", JsonUtils.toJsonString(params));
            log.info("富友审核req参数:{}", JsonUtils.toJsonString(params));
            String response = HttpUtils.post(url, requestParams);
            // 响应报文验签
            log.info("富友审核返回参数:{}", response);
            FuYouJsonResponse fuYouJsonResponse = JsonUtils.parseObject(response, FuYouJsonResponse.class);
            if (FuYouConstant.REQUEST_SUCCESS.equals(fuYouJsonResponse.getRet_code())) {
                // 上传图片至ftp
                channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.AUDITING);
            }
            else {
                channelMerchantBusinessContext.setRemark(fuYouJsonResponse.getRet_msg());
                channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
                // 回到上一个状态
                channelMerchantBusinessContext.setAuditStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.SIGN);
                channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            }
        }
        catch (

        Exception e) {
            e.printStackTrace();
            log.error("富友审核请求失败,失败信息 message: {}", e.getMessage());
            channelMerchantBusinessContext.setRemark("富友审核请求失败,失败信息" + e.getMessage());
            channelMerchantBusinessContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantBusinessContext.setAccessStatus(MerchantEnum.ACCESS_STATUS.APPROVE_REFUSE);
        }
    }

    /**
     * 进件查询
     * 
     * @param channelMerchantAccessQueryContext
     */
    public void accessQueryRequest(ChannelMerchantAccessQueryContext channelMerchantAccessQueryContext) {
        CommonResult<FuYouConfig> fuYouConfigCommonResult = channelConfig(channelMerchantAccessQueryContext.getProviderChannelConfig());
        // 配置转换
        if (!fuYouConfigCommonResult.isSuccess()) {
            channelMerchantAccessQueryContext.setRemark(fuYouConfigCommonResult.getMsg());
            channelMerchantAccessQueryContext.setProcessStatus(Boolean.FALSE);
            return;
        }
        FuYouConfig fuYouConfig = fuYouConfigCommonResult.getData();
        MerchantAccessInfoDO merchantAccessInfo = channelMerchantAccessQueryContext.getMerchantAccessInfo();
        // 1. 数据初始化
        try {
            // 新增参数转换
            String requestId = IdUtils.getSnowflake().nextIdStr();
            Map<String, Object> params = new HashMap<>();
            params.put("traceNo", requestId);
            params.put("insCd", fuYouConfig.getInsCd());
            params.put("mchntCd", merchantAccessInfo.getSubMchId());
            params.put("sign", SignUtils.getMerchantSign(params, fuYouConfig));
            String requestUrl = FuYouConstant.MERCHANT_QUERY;
            // 记录请求参数
            String url = domain(channelMerchantAccessQueryContext.isTest()) + requestUrl;
            log.info("富友查询商户信息请求参数:{}", params);
            Map<String, String> requestParams = new HashMap<>();
            requestParams.put("req", JsonUtils.toJsonString(params));
            log.info("富友查询商户信息req参数:{}", JsonUtils.toJsonString(params));
            String response = HttpUtils.post(url, requestParams);
            // 响应报文验签
            log.info("富友查询商户信息返回参数:{}", response);
            FuYouMerchantParamsHandle.merchantQueryParamsParse(response, channelMerchantAccessQueryContext);
        }
        catch (Exception e) {
            e.printStackTrace();
            log.error("富友开户查询请求失败,失败信息 message: {}", e.getMessage());
            // channelMerchantAccessContext.setRemark("富友个人开户请求失败,失败信息" + e.getMessage());
            // channelMerchantAccessContext.setProcessStatus(Boolean.FALSE);
            // channelMerchantAccessContext.setAccessStatus(MerchantEnum.CHANNEL_CONFIG_STATUS.APPROVE_REFUSE);
        }

    }

}
